package com.belle.sfsdfasdfsdf;

import com.belle.sfsdfasdfsdf.domain.ScheduleJob;
import com.belle.sfsdfasdfsdf.service.JobService;
import com.belle.sfsdfasdfsdf.support.QuartzJobFactory;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 项目启动之后运行
 * @author sxl
 * @date 2018/9/18 0018 14:48
 */
@Component
public class AfterSpringStarted implements ApplicationRunner {
	
	@Autowired
	private SchedulerFactoryBean schedulerFactoryBean;
	
	@Autowired
	private JobService jobService;
	
	@Override
	public void run(ApplicationArguments args){
		if(schedulerFactoryBean != null) {
			Scheduler scheduler = schedulerFactoryBean.getScheduler();
			//启动一个监测线程监测定时器的状态
			if(scheduler != null) {
				try {
					if(!scheduler.isStarted()) {
						restartScheduler();
						new Thread(() -> {
							while(true) {
								try {
									Thread.sleep(10 * 1000);
									if(scheduler.isShutdown()) {
										restartScheduler();
									}
								} catch(InterruptedException e) {
									e.printStackTrace();
								} catch(SchedulerException e) {
									e.printStackTrace();
								}
							}
						}).start();
					}
				} catch(SchedulerException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 从数据库查询任务数据并重启scheduler
	 * @author sxl
	 * @date 2018/9/18 0018 14:39
	 * @param
	 * @return void
	 */
	private void restartScheduler() throws SchedulerException {
		List<ScheduleJob> allAvailable = jobService.findAllAvailable();
		if(CollectionUtils.isEmpty(allAvailable)) {
			return;
		}
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		for(ScheduleJob scheduleJob : allAvailable) {
			if(StringUtils.isEmpty(scheduleJob.getJobGroup()) ||
					StringUtils.isEmpty(scheduleJob.getJobName()) ||
					StringUtils.isEmpty(scheduleJob.getCronExpression())) {
				continue;
			}
			if(scheduler.checkExists(TriggerKey.triggerKey(scheduleJob.getJobName(),
					scheduleJob.getJobGroup()))) {
				continue;
			}
			CronTrigger trigger = null;
			//创建任务
			JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class)
					.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup())
					.build();
			
			jobDetail.getJobDataMap().put("scheduleJob", scheduleJob);
			
			//表达式调度构建器
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob
					.getCronExpression());
			
			//按新的cronExpression表达式构建一个新的trigger
			trigger = TriggerBuilder.newTrigger()
					.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup())
					.withSchedule(scheduleBuilder)
					.build();
			
			scheduler.scheduleJob(jobDetail, trigger);
		}
		scheduler.start();
	}
}
